﻿using System;
using System.Drawing;
using GeoSketch2.Core;
using System.Xml;
using System.IO;

namespace GeoSketch2.Archaeo
{
    /// <summary>
    /// The base class for all Archaeological objects
    /// </summary>
    public abstract class BaseArchaeoDrawableObject:BaseDrawableObject
    {
        #region XMLElementsName
#pragma warning disable 1591
        public const string XML_CreationTime = "CreationTime";
        public const string XML_Comment = "Comment";
        public const string XML_ByLayer = "ByLayer";
#pragma warning restore 1591
        #endregion

        #region Fields
        /// <summary>
        /// The excavation unit containing the object
        /// </summary>
        public ExcavationArea ExcavationArea;

        /// <summary>
        /// The creation time of the object
        /// </summary>
        public DateTime CreationTime;

        /// <summary>
        /// The comment about the object
        /// </summary>
        public string Comment; 
        #endregion

        #region Constructor

        /// <summary>
        /// A geosketch Archaeological object
        /// </summary>
        /// <param name="Layer">The layer of the object</param>
        /// <param name="Color">The color of the object</param>
        /// <param name="LineType">The line type of the object</param>
        /// <param name="ExcavationUnit">The excavation unit of the object</param>
        /// <param name="Comment">The comment about of the object</param>
        /// <param name="CreationTime">The date of creation of the object</param>
        public BaseArchaeoDrawableObject(Layer Layer, Color Color, LineType LineType, ExcavationArea ExcavationArea, string Comment, DateTime CreationTime)
            : base(Layer, Color, LineType)
        {
            this.ExcavationArea = ExcavationArea;
            this.Comment = Comment;
            this.CreationTime = CreationTime;
        }

        /// <summary>
        /// A geosketch Archaeological object
        /// </summary>
        /// <param name="Xr">The Xml Reader to read from</param>
        /// <param name="Site">The excavation site</param>
        public BaseArchaeoDrawableObject(XmlReader Xr, ArchaeoProject Project)
        {
            Xr.ReadToFollowing(XML_BaseInfos);

            #region Object Layer
            Xr.ReadToFollowing(XML_Layer);
            this.Layer = Project.GetLayerFromName(Xr.ReadString());
            #endregion

            #region Object Color
            Xr.ReadToFollowing(XML_Color);
            string color = Xr.ReadString();
            if (color == XML_ByLayer)
            {
                this.Color = ColorByLayer();
            }
            else
            {
                this.Color = System.Drawing.Color.FromArgb(Convert.ToInt32(color, Core.Vars.Setup.GeoSketch.NumberFormat)).GetNamedColor();
            }
            #endregion

            #region Object LineType
            Xr.ReadToFollowing(XML_LineType);
            string linetype = Xr.ReadString();
            if (linetype == XML_ByLayer)
            {
                this.LineType = LineTypeByLayer();
            }
            else
            {
                this.LineType = Project.GetLineTypeFromId(Convert.ToInt32(linetype, Core.Vars.Setup.GeoSketch.NumberFormat));
            }
            #endregion

            #region Object ExcavationUnit
            Xr.ReadToFollowing(typeof(ExcavationArea).FullName);
            this.ExcavationArea = Project.GetExcavationAreaFromName(Xr.ReadString());
            #endregion

            #region Object Creation Time
            Xr.ReadToFollowing(XML_CreationTime);
            this.CreationTime = DateTime.FromBinary(Convert.ToInt64(Xr.ReadString(), Core.Vars.Setup.GeoSketch.NumberFormat));
            #endregion

            #region Object Comment
            Xr.ReadToFollowing(XML_Comment);
            this.Comment = Xr.ReadString();
            #endregion

            Xr.ReadEndElement();
        }
        #endregion

        #region Methods
        /// <summary>
        /// An abstract method that every drawable object should implement, to save themselves to a file
        /// </summary>
        /// <param name="Xw">The Xml Writer to write to</param>
        public abstract void ToFile(XmlWriter Xw);

        /// <summary>
        /// A virtual method that every drawable object can implement, to save themselves to a file
        /// </summary>
        /// <param name="Tw">The TextWriter to write to</param>
        public virtual void ToDXFr13(TextWriter Tw)
        {
        }

        /// <summary>
        /// Writes the base infos of an object to a file
        /// </summary>
        /// <param name="Xw">The Xml Writer to write to</param>
        public void BaseInfosToFile(XmlWriter Xw)
        {
            Xw.WriteStartElement(XML_BaseInfos);

            #region Object Layer
            Xw.WriteStartElement(XML_Layer);
            Xw.WriteString(this.Layer.Name);
            Xw.WriteEndElement();
            #endregion

            #region Object Color
            Xw.WriteStartElement(XML_Color);
            if (this.IsColorByLayer)
            {
                Xw.WriteString(XML_ByLayer);
            }
            else
            {
                Xw.WriteString(this.Color.ToArgb().ToString(Core.Vars.Setup.GeoSketch.NumberFormat));
            }
            Xw.WriteEndElement();
            #endregion

            #region Object LineType
            Xw.WriteStartElement(XML_LineType);
            if (this.IsLineTypeByLayer)
            {
                Xw.WriteString(XML_ByLayer);
            }
            else
            {
                Xw.WriteString(this.LineType.Id.ToString(Core.Vars.Setup.GeoSketch.NumberFormat));
            }
            Xw.WriteEndElement();
            #endregion

            #region Object ExcavationUnit
            Xw.WriteStartElement(typeof(ExcavationArea).FullName);
            if (this.ExcavationArea != null)
            {
                Xw.WriteString(this.ExcavationArea.Name);
            }
            else
            {
                Xw.WriteString("");
            }
            Xw.WriteEndElement();
            #endregion

            #region Object Creation Time
            Xw.WriteStartElement(XML_CreationTime);
            Xw.WriteString(this.CreationTime.ToBinary().ToString(Core.Vars.Setup.GeoSketch.NumberFormat));
            Xw.WriteEndElement();
            #endregion

            #region Object Comment
            Xw.WriteStartElement(XML_Comment);
            Xw.WriteString(this.Comment);
            Xw.WriteEndElement();
            #endregion

            Xw.WriteEndElement();
        }

        /// <summary>
        /// Writes the base infos of an object to a file
        /// </summary>
        /// <param name="Tw">The TextWriter to write to</param>
        protected void BaseInfosToDXFR13(TextWriter Tw)
        {
            #region Object LineType
            Tw.WriteLine("6");
            if (this.IsLineTypeByLayer)
            {
                Tw.WriteLine("BYLAYER");
            }
            else
            {
                Tw.WriteLine(this.LineType.Id.ToString(Core.Vars.Setup.GeoSketch.NumberFormat));
            } 
            #endregion

            #region Object Layer
            Tw.WriteLine("8");
            Tw.WriteLine(this.Layer.Name); 
            #endregion

            #region Object Color
            Tw.WriteLine("62");
            if (this.IsColorByLayer)
            {
                Tw.WriteLine("256");
            }
            else
            {
                Tw.WriteLine(AutoCadIndexedColor.GetNearestAutoCadColor(this.Color).ACI.ToString(Core.Vars.Setup.GeoSketch.NumberFormat));
            }
            #endregion
        }
        #endregion

    }
}
